import Handsontable from "handsontable";
import { undoManager, checkSelection } from "../util/Utils.js";
import Chart from "chart.js/auto";
import { color } from "chart.js/helpers";
import { MessageBox } from "element-ui";
import $ from "jquery";
const chartColors = {
  red: "rgb(255, 99, 132)",
  orange: "rgb(255, 159, 64)",
  yellow: "rgb(255, 205, 86)",
  green: "rgb(75, 192, 192)",
  blue: "rgb(54, 162, 235)",
  purple: "rgb(153, 102, 255)",
  grey: "rgb(201, 203, 207)"
};

export default {
  builderChart (designer, category) {
    const { context } = designer;
    if (!checkSelection(context)) {
      return;
    }
    const hot = context.hot;
    const selected = hot.getSelected()[0];
    const startRow = selected[0];
    const startCol = selected[1];
    const endRow = selected[2];
    const endCol = selected[3];

    let cellDef = context.getCell(startRow, startCol);
    let oldValue = cellDef.value;
    let oldCellData = hot.getDataAtCell(startRow, startCol);
    hot.setDataAtCell(startRow, startCol, "");
    cellDef.value = {
      type: "chart",
      chart: this._newChart(category)
    };
    hot.render();
    context.isModify = true;
    Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
    undoManager.add({
      redo: () => {
        cellDef = context.getCell(startRow, startCol);
        oldValue = cellDef.value;
        oldCellData = hot.getDataAtCell(startRow, startCol);
        hot.setDataAtCell(startRow, startCol, "");
        cellDef.value = {
          type: "chart",
          chart: this._newChart(category)
        };
        hot.render();
        context.isModify = true;
        Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
      },
      undo: () => {
        cellDef = context.getCell(startRow, startCol);
        cellDef.value = oldValue;
        hot.setDataAtCell(startRow, startCol, oldCellData);
        hot.render();
        context.isModify = true;
        Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
      }
    });
  },
  renderChart (container, context, rowIndex, colIndex) {
    const cellDef = context.getCell(rowIndex, colIndex);

    const hot = context.hot;
    const $td = container;
    const rowSpan = $td.prop("rowspan");
    const colSpan = $td.prop("colspan");
    let width = -2;
    let height = -2;
    const rowStart = rowIndex;
    const rowEnd = rowIndex + rowSpan;
    for (let i = rowStart; i < rowEnd; i++) {
      height += hot.getRowHeight(i);
    }
    const colStart = colIndex;
    const colEnd = colIndex + colSpan;
    for (let i = colStart; i < colEnd; i++) {
      width += hot.getColWidth(i);
    }
    container.empty();
    const canvas = $(`<div style="position: relative;"><canvas style="width: ${width}px;height: ${height}px;;"></canvas></div>`);
    container.append(canvas);
    const type = cellDef.value.chart.dataset.type;
    let data = null;
    const options = {};
    let chartType;

    const defaultOptions = cellDef.value.chart.options;
    if (defaultOptions) {
      for (const option of defaultOptions) {
        options[option.type] = option;
      }
    }
    const xaxes = cellDef.value.chart.xaxes;
    if (xaxes) {
      let scales = options.scales;
      if (!scales) {
        scales = {};
        options.scales = scales;
      }
      let xAxes = scales.xAxes;
      if (!xAxes) {
        xAxes = [];
        scales.xAxes = xAxes;
      }
      if (xaxes.rotation) {
        let ticks = xaxes.ticks;
        if (!ticks) {
          ticks = {};
          xaxes.ticks = ticks;
        }
        ticks.minRotation = xaxes.rotation;
      }
      xAxes.push(xaxes);
    }
    const yaxes = cellDef.value.chart.yaxes;
    if (yaxes) {
      let scales = options.scales;
      if (!scales) {
        scales = {};
        options.scales = scales;
      }
      let yAxes = scales.yAxes;
      if (!yAxes) {
        yAxes = [];
        scales.yAxes = yAxes;
      }
      if (yaxes.rotation) {
        let ticks = yaxes.ticks;
        if (!ticks) {
          ticks = {};
          yaxes.ticks = ticks;
        }
        ticks.minRotation = yaxes.rotation;
      }
      yAxes.push(yaxes);
    }

    switch (type) {
      case "bar":
        chartType = "bar";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5", "类型6"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              borderWidth: 1,
              data: [21, 25, 8, 12, 31, 19]
            },
            {
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              data: [11, 13, 18, 9, 23, 29]
            }
          ]
        };
        break;
      case "horizontalBar":
        chartType = "horizontalBar";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5", "类型6"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              borderWidth: 1,
              data: [21, 25, 8, 12, 31, 19]
            },
            {
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              data: [11, 13, 18, 9, 23, 29]
            }
          ]
        };
        break;
      case "line":
        chartType = "line";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5", "类型6"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              borderWidth: 1,
              fill: false,
              data: [21, 25, 8, 12, 31, 19]
            },
            {
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              fill: false,
              data: [11, 13, 18, 9, 23, 29]
            }
          ]
        };
        break;
      case "area":
        chartType = "line";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5", "类型6"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              borderWidth: 1,
              data: [21, 25, 8, 12, 31, 19]
            },
            {
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              data: [11, 13, 18, 9, 23, 29]
            }
          ]
        };
        options.scales = {
          yAxes: [
            {
              stacked: true
            }
          ]
        };
        break;
      case "pie":
        chartType = "pie";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green],
              data: [21, 25, 8, 12]
            }
          ]
        };
        break;
      case "doughnut":
        chartType = "doughnut";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green],
              data: [21, 25, 8, 12]
            }
          ]
        };
        break;
      case "radar":
        chartType = "radar";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              borderWidth: 1,
              data: [21, 25, 8, 12, 31]
            },
            {
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              data: [11, 13, 18, 9, 23, 9]
            }
          ]
        };
        break;
      case "polarArea":
        chartType = "polarArea";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4"],
          datasets: [
            {
              label: "系列1",
              backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green],
              data: [21, 25, 12, 31]
            }
          ]
        };
        break;
      case "scatter":
        chartType = "scatter";
        data = {
          datasets: [
            {
              label: "系列1",
              borderColor: chartColors.red,
              backgroundColor: color(chartColors.red)
                .alpha(0.2)
                .rgbString(),
              data: [
                { x: 10, y: 10 },
                { x: 5, y: 15 },
                { x: 8, y: 12 },
                { x: 18, y: 10 }
              ]
            },
            {
              label: "系列2",
              borderColor: chartColors.blue,
              backgroundColor: color(chartColors.blue)
                .alpha(0.2)
                .rgbString(),
              data: [
                { x: 13, y: 6 },
                { x: 25, y: 10 },
                { x: 18, y: 11 },
                { x: 14, y: 16 }
              ]
            }
          ]
        };
        break;
      case "bubble":
        chartType = "bubble";
        data = {
          datasets: [
            {
              label: "系列1",
              borderColor: chartColors.red,
              backgroundColor: color(chartColors.red)
                .alpha(0.2)
                .rgbString(),
              data: [
                { x: 10, y: 10, r: 4 },
                { x: 5, y: 15, r: 6 },
                { x: 8, y: 12, r: 2 },
                { x: 18, y: 10, r: 8 }
              ]
            },
            {
              label: "系列2",
              borderColor: chartColors.blue,
              backgroundColor: color(chartColors.blue)
                .alpha(0.2)
                .rgbString(),
              data: [
                { x: 13, y: 6, r: 3 },
                { x: 25, y: 10, r: 9 },
                { x: 18, y: 11, r: 2 },
                { x: 14, y: 16, r: 10 }
              ]
            }
          ]
        };
        break;
      case "mix":
        chartType = "bar";
        data = {
          labels: ["类型1", "类型2", "类型3", "类型4", "类型5", "类型6"],
          datasets: [
            {
              type: "line",
              label: "系列1",
              backgroundColor: color(chartColors.red)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.red,
              data: [21, 25, 8, 12, 31, 19]
            },
            {
              type: "bar",
              label: "系列2",
              backgroundColor: color(chartColors.blue)
                .alpha(0.5)
                .rgbString(),
              borderColor: chartColors.blue,
              borderWidth: 1,
              data: [11, 13, 18, 9, 23, 29]
            }
          ]
        };
        break;
      default:
        MessageBox.alert("不能识别的图表类型：" + type);
    }
    const optionList = cellDef.value.chart.options || [];
    for (const op of optionList) {
      switch (op.type) {
        case "title":
          if (op.display) {
            options.title = {
              display: true,
              position: op.position,
              text: op.text
            };
          }
          break;
        case "legend":
          if (op.display) {
            options.legend = {
              display: true,
              position: op.position
            };
          } else {
            options.display = {
              display: false
            };
          }
          break;
        case "layout":
          if (op.padding) {
            options.layout = {
              padding: {
                left: op.padding.left,
                right: op.padding.right,
                top: op.padding.top,
                bottom: op.padding.bottom
              }
            };
          }
      }
    }
    this.chart = new Chart(canvas.children("canvas").get(0), {
      type: chartType,
      data: data,
      options: options || {}
    });
  },
  _newChart (category) {
    return {
      dataset: {
        type: category,
        seriesType: "text"
      },
      options: [
        {
          display: true,
          position: "top",
          fontSize: 14,
          fontColor: "#666",
          fontStyle: "bold",
          padding: 10,
          text: null,
          type: "title"
        },
        {
          display: true,
          position: "bottom",
          labels: null,
          type: "legend"
        },
        {
          duration: 1000,
          easing: "easeOutQuart",
          type: "animation"
        }
      ],
      plugins: [
        {
          display: true,
          name: "data-labels"
        }
      ]
    };
  }
};
